package com.jeff.learn.array;

import java.util.function.IntConsumer;

/**
 * 自定义实现一个int数组，可以动态扩容
 *
 * @author yaojianfeng
 */
public class DynamicIntArray {
    /**
     * 数组
     */
    private int[] arr;

    /**
     * 数组的大小
     */
    private int size;

    /**
     * 数组的容量
     */
    private int capacity;

    /**
     * 构造函数，默认容量为8
     */
    public DynamicIntArray() {
        this(8);
    }

    /**
     * @param capacity 数组的初始容量
     */
    public DynamicIntArray(int capacity) {
        this.capacity = capacity;
        this.arr = new int[capacity];
        this.size = 0;
    }

    /**
     * 添加元素到数组中
     * 使用尾插法,需要做扩容检查
     *
     * @param num 元素的值
     */
    public void addLast(int num) {
        // 如果数组容量不够，则扩容
        if (size == capacity) {
            extracted();
        }
        //尾插法
        arr[size++] = num;
    }

    /**
     * 添加元素到数组中的指定位置
     *
     * @param index 元素的位置
     * @param num   元素的值
     */
    public void add(int index, int num) {
        // 1.首先检查参数合法性,对index进行合法性检查
        if (!checkIndex(index)) {
            throw new IndexOutOfBoundsException("Index: " + index + ", capacity: " + capacity);
        }
        // 如果数组容量不够，则扩容
        if (size == capacity) {
            extracted();
        }
        // 如果在index位置原来就有元素,则从index开始将剩余元素后移一位,空出index位置 如果index位置没有元素,则直接将num放到index位置
        if (index >= 0 && index < size) {
            System.arraycopy(arr, index, arr, index + 1, size - index);
        }
        arr[index] = num;
        size++;
    }

    /**
     * 检查index是否合法
     *
     * @param index 元素的位置
     * @return 合法返回true，不合法返回false
     */
    private boolean checkIndex(int index) {
        return index >= 0 && index < capacity;
    }

    /**
     * 扩容检查，如果数组容量不够，则扩容
     */
    private void extracted() {

        int newCapacity = capacity *2;

        int[] newArr = new int[newCapacity];
        System.arraycopy(arr, 0, newArr, 0, size);
        //更新数组和容量
        arr = newArr;
        capacity = newCapacity;
    }


    public int get(int index) {
        return arr[index];
    }

    public int size() {
        return size;
    }

    public void foreach(IntConsumer action) {
        for (int i = 0; i < capacity; i++) {
            action.accept(arr[i]);
        }
    }

    /**
     * 打印数组
     * 将数组中的每个'槽位的元素'打印出来
     */
    public void print() {
        for (int i = 0; i < capacity; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }

    /**
     * 删除指定位置的元素，并返回该元素的值
     *
     * @param index 元素的位置
     * @return 该元素的值
     */
    public int delete(int index) {
        if (index < 0 || index >= capacity) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        }
        int num = arr[index];
        for (int i = index + 1; i < capacity; i++) {
            arr[i - 1] = arr[i];
        }
        size--;
        return num;
    }


    /**
     * 删除指定元素的值，并返回该元素的位置
     *
     * @param num 元素的值
     * @return 该元素的位置
     */
    public int deleteValue(int num) {
        for (int i = 0; i < capacity; i++) {
            if (get(i) == num) {
                delete(i);
                return i;
            }
        }
        return -1;
    }

    public void clear() {
        size = 0;
        arr = new int[8];
        capacity = 8;
    }


    public boolean isEmpty() {
        return size == 0;
    }

    public boolean contains(int num) {
        for (int i = 0; i < capacity; i++) {
            if (get(i) == num) {
                return true;
            }
        }
        return false;
    }


    public int indexOf(int num) {
        for (int i = 0; i < capacity; i++) {
            if (get(i) == num) {
                return i;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        DynamicIntArray dynamicIntArray = new DynamicIntArray();
        for (int i = 0; i < 30; i++) {
            dynamicIntArray.addLast(i);
        }

        dynamicIntArray.delete(10);
        dynamicIntArray.print();
        dynamicIntArray.delete(20);
        dynamicIntArray.print();
        int deleteIndex = dynamicIntArray.deleteValue(29);
        System.out.println("deleteIndex: " + deleteIndex);
        dynamicIntArray.print();
        System.out.println(dynamicIntArray.get(3));
        dynamicIntArray.clear();
        dynamicIntArray.print();
        dynamicIntArray.addLast(1);
        dynamicIntArray.addLast(2);
        dynamicIntArray.addLast(3);
        dynamicIntArray.addLast(4);
        dynamicIntArray.addLast(5);
        dynamicIntArray.print();
        dynamicIntArray.add(2, 100);
        dynamicIntArray.print();
        dynamicIntArray.add(3, 200);
        dynamicIntArray.add(4, 300);
        dynamicIntArray.add(5, 400);
        dynamicIntArray.print();
        System.out.println(dynamicIntArray.contains(401));

        IntConsumer consumer1 = num -> System.out.println("第一次消费结果是:" + num);
        IntConsumer consumer2 = num -> System.out.println("第二次消费结果是:" + num * 100);
        IntConsumer consumer3 = consumer1.andThen(consumer2);

        dynamicIntArray.foreach(consumer3);

        dynamicIntArray.foreach(num -> {
            System.out.println("第一次消费结果是:" + num);
            System.out.println("第二次消费结果是:" + num * 100);
        });


    }
}












